package dao

import (
	"errors"
	"gorm.io/gorm"
	"time"
	"yundian/internel/app/helper"
	"yundian/internel/app/helper/request"
	"yundian/internel/app/models/devices"
	"yundian/internel/app/models/message"
	"yundian/internel/app/models/orders"
	"yundian/internel/pkg/dingo"
	"yundian/internel/pkg/dingo/global"
)

// -------------------- dao层 - 订单相关操作 -----------------------//

type MessageDao struct {
}

func NewMessageDao() *MessageDao {
	return &MessageDao{}
}

// 查询微信订阅消息
func (d *MessageDao) GetFixedRemindRss(param *message.MessageFixedModel) *dingo.ErrorWrap {
	var list []*message.MessageFixedModel
	status := []uint8{helper.TypeNumMessageStatusWait, helper.TypeNumMessageStatusFail}

	db := global.Orm.Where("status IN (?)", status).Where("type=? AND openid=?", param.Type, param.Openid)
	db.Find(&list)

	return dingo.ErrorIf(db.Error, list)
}

// 创建微信订阅消息
func (d *MessageDao) InsertFixedRemindRss(param *request.WxFixedRemindRss) *dingo.ErrorWrap {
	deviceInfo := NewDeviceDao().GetDeviceByDeviceSn(param.DeviceSn).Unwrap().(*devices.DeviceModel)
	if deviceInfo.ID <= 0 {
		return dingo.ErrorIf(errors.New("empty"), nil)
	}

	dbInfo := &message.MessageFixedDb{
		Openid:     param.Openid,
		PlaceId:    deviceInfo.PlaceId,
		PlaceName:  deviceInfo.PlaceName,
		DeviceSn:   param.DeviceSn,
		TemplateId: param.TemplateId,
		Status:     3,
		Type:       param.Type,
	}
	db := global.Orm.Debug().Create(&dbInfo)
	return dingo.ErrorIf(db.Error)
}

// 根据ID修改消息状态
func (d *MessageDao) UpdateIdFixedRemindRss(id int, status uint8) *dingo.ErrorWrap {
	db := global.Orm.Debug().Table("wx_message_send_fixed").Where("id=?", id).Update("status", status)
	return dingo.ErrorIf(db.Error, db.Error == nil)
}

// 查询待推送消息
func (d *MessageDao) GetWaitFixedRemindRss(typeNum uint8, minTime string) *dingo.ErrorWrap {
	var list []*message.MessageFixedModel
	status := []uint8{helper.TypeNumMessageStatusWait, helper.TypeNumMessageStatusFail}
	db := global.Orm.Where("status IN (?)", status).Where("type=?", typeNum)
	if minTime != "" {
		db.Where("create_time<?", minTime)
	}

	db.Find(&list)

	return dingo.ErrorIf(db.Error, list)
}

// 创建微信订阅消息
func (d *MessageDao) InsertOrderRemindRss(param *request.WxOrderRemindRss) *dingo.ErrorWrap {
	ordersInfo := NewOrderDao().GetOrderDetail(param.OrderId).Unwrap().(orders.OrderDetail)
	if ordersInfo.Id <= 0 {
		return dingo.ErrorIf(errors.New("empty"), nil)
	}

	data := map[string]interface{}{
		"status":           helper.TypeNumMessageStatusWait,
		"countdown_second": param.CountdownSecond,
		"place_name":       ordersInfo.PlaceName,
		"product_id":       ordersInfo.ProductId,
		"device_sn":        ordersInfo.DeviceSn,
		"trade_no":         ordersInfo.TradeNo,
		"openid":           ordersInfo.Openid,
		"template_id":      param.TemplateId,
		"create_time":      time.Unix(int64(ordersInfo.PayAt), 0),
	}
	db := global.Orm.Debug().Table("wx_message_send").Create(data)
	return dingo.ErrorIf(db.Error)
}

// 查询待推送消息
func (d *MessageDao) GetWaitOrderRemindRss(templateIdFinish, templateIdOrder string) *dingo.ErrorWrap {
	var list []*message.OrderAndMessageModel
	status := []uint8{helper.TypeNumMessageStatusWait, helper.TypeNumMessageStatusFail}

	db := global.Orm.Debug().Table("wx_message_send wms").
		Select(`wms.id, wms.product_id, wms.trade_no, wms.device_sn, wms.place_name, wms.openid, wms.template_id, wms.status, wms.countdown_second,
		DATE_FORMAT(wms.create_time, '%Y-%m-%d %T') create_time,o.end_at,o.create_at,o.settlement_money,o.state`).
		Joins("left join orders o on wms.trade_no=o.trade_no")
	db.Where("wms.status in (?)", status)
	db.Where("((wms.template_id=? and o.state=? and wms.create_time<?) or (wms.template_id=? and o.state=? and now()<?))",
		templateIdOrder, helper.TypeNumOrderStatusService,
		gorm.Expr("DATE_SUB(NOW(), INTERVAL wms.countdown_second SECOND)"),
		templateIdFinish, helper.TypeNumOrderStatusFinish,
		gorm.Expr("DATE_ADD(FROM_UNIXTIME(o.end_at), INTERVAL 24 HOUR)"),
	)
	db.Find(&list)

	return dingo.ErrorIf(db.Error, list)
}

// 根据ID修改消息状态
func (d *MessageDao) UpdateIdOrderRemindRss(id int, status uint8) *dingo.ErrorWrap {
	db := global.Orm.Debug().Table("wx_message_send").Where("id=?", id).Update("status", status)

	return dingo.ErrorIf(db.Error, db.Error == nil)
}
